﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using COFE.Core;
using COFE.Core.Profile;
using COFE.Core.Utils;
using COFE.Core.Entry;

namespace COFE.Core.Lister
{

    public abstract class DirectoryListerBase<T> : IDirectoryLister
    {
        #region Constructor

        public DirectoryListerBase(IFactory<IDirectoryLister> factory, string listerKey)
        {
            _factory = factory;
            ListerKey = listerKey;
        }

        #endregion

        #region Methods


        protected T getEmbeddedItem(IInternalFileSystemInfoExA entry)
        {
            return (T)entry.GetProperty(InternalProperties.EmbeddedEntry).Value;  
        }

        public abstract IEnumerable<IFileSystemInfo> List(IInternalDirectoryInfoExA parent, EntryConstructionFlags flags);
        
        public virtual IInternalDirectoryInfoExA GetParent(IInternalFileSystemInfoExA entry)
        {
            T embeddedEntry = getEmbeddedItem(entry);
            T parentEntry = _getParent(embeddedEntry);
            if (parentEntry != null)
                return COFEShared.EntryConstructor.CreateDirectory(ListerKey, CreatePropertyProvider(parentEntry));                
            return null;
        }

        public virtual void Expand(IInternalFileSystemInfoExA entry)
        {
            T embeddedEntry = getEmbeddedItem(entry);
            _expand(embeddedEntry, entry.TempPath);
        }

        public virtual int GetPosition(IInternalFileSystemInfoExA entry)
        {
            T embeddedEntry = getEmbeddedItem(entry);
            return _getPosition(embeddedEntry);
        }

        public virtual void SetPosition(IInternalFileSystemInfoExA entry, int position)
        {
            T embeddedEntry = getEmbeddedItem(entry);
            _setPosition(embeddedEntry, position);
        }

        public abstract IDirectoryController CreateController();

        public abstract IStreamProvider CreateStreamProvider();

        public abstract IPropertyProvider CreatePropertyProvider(T item);


        #endregion

        #region Data

        private IFactory<IDirectoryLister> _factory = null;

        protected Func<T, IEnumerable<T>> _list = (item) => { return new List<T>(); };
        protected Func<T, bool> _isDirectory = (item) => { return false; };
        protected Func<T, T> _getParent = (item) => { return default(T); };

        protected Action<T, string> _expand = (item, tempPath) => { };
        protected Func<T, int> _getPosition = (item) => { return -1; };
        protected Action<T, int> _setPosition = (item, pos) => { };

        #endregion

        #region Public Properties


        public string ListerKey { get; set; }

        public IFactory<IDirectoryLister> Factory { get { return _factory; } }

        #endregion


    }
}
